<?php

namespace Xin\Hyperf\Fortify\Process;

use Hyperf\Context\ApplicationContext;
use Hyperf\Contract\ProcessInterface;
use Hyperf\Server\ServerFactory;
use Hyperf\Server\ServerInterface;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Swoole\Coroutine\Server as CoroutineServer;
use Swoole\Server;

class ProcessManager
{
    /**
     * @param object|callable $handler
     * @return CustomProcess
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public static function startWithHandler($handler, $options = [])
    {
        $container = ApplicationContext::getContainer();
        if (is_string($handler)) {
            if (class_exists($handler)) {
                $handler = $container->get($handler);
            }
        }
        $process = new CustomProcess($container, $handler);
        return value(self::start($process));
    }

    /**
     * @param ProcessInterface $processInstance
     * @return ProcessInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public static function start(ProcessInterface $processInstance)
    {
        $server = self::getNativeServer();
        if ($processInstance->isEnable($server)) {
            $processInstance->bind($server);
        }

        return $processInstance;
    }

    /**
     * @return ServerInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public static function getHyperfServer(): ServerInterface
    {
        return ApplicationContext::getContainer()->get(ServerFactory::class)->getServer();
    }

    /**
     * @return CoroutineServer|Server
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public static function getNativeServer()
    {
        return self::getHyperfServer()->getServer();
    }

}
